package com.sta.oldman.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sta.oldman.common.ResponseVO;
import com.sta.oldman.dao.mapper.UserMapper;
import com.sta.oldman.enums.CheckUserEnum;
import com.sta.oldman.dao.User;
import com.sta.oldman.model.req.*;
import com.sta.oldman.model.resp.LoginByUsernameResp;
import com.sta.oldman.service.UserService;
import com.sta.oldman.utils.*;
import jakarta.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author: LunBoWang
 * @description: 用户接口实现类
 * @date: 2025/7/14 上午11:01
 * @version: 1.0
 */
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private VerificationCodeService    verificationCodeService;

    /**
     * 注册用户
     * @param req 注册请求
     * @return 注册结果
     */
    @Override
    public ResponseVO register(RegisterReq req) {
        //校验信息（查询用户是否存在）
        //存在，返回用户已存在
        //校验手机号
        //校验用户名和密码
        ResponseVO res = checkUserOrPass(req.getUsername(), req.getPassword());
        if (res != null) return res;
        //查询用户是否存在
        if (checkUsername(req.getUsername())) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_EXIST.getCode(), CheckUserEnum.USER_EXIST.getMessage());
        }
        //不存在，注册用户
        //生成用户id
        Long userId = SnowFlakeUtil.getSnowFlakeId();
        User user = new User();
        BeanUtils.copyProperties(req, user);
        user.setUserId(userId);
        //保存用户信息
        int insert = userMapper.insert(user);
        if (insert != 1) {
            return ResponseVO.errorResponse(CheckUserEnum.REGISTER_ERROR.getCode(), CheckUserEnum.REGISTER_ERROR.getMessage());
        }
        //返回注册成功
        return ResponseVO.successResponse("注册成功");
    }

    @Override
    public ResponseVO loginByPhone(LoginByPhoneReq req) {
        return null;
    }

    /**
     * 邮箱登录
     * @param req 邮箱登录请求
     * @return 登录结果
     */
    @Override
    public ResponseVO loginByEmail(LoginByEmailReq req) {
        if(!Check.isValidEmail(req.getEmail())){
            return ResponseVO.errorResponse(CheckUserEnum.EMAIL_ERROR.getCode(), CheckUserEnum.EMAIL_ERROR.getMessage());
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", req.getEmail());
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_NOT_EXIST.getCode(), CheckUserEnum.USER_NOT_EXIST.getMessage());
        }
        boolean b = verificationCodeService.verifyCode(req.getEmail(), req.getCode());
        if (!b) {
            return ResponseVO.errorResponse(CheckUserEnum.CODE_ERROR.getCode(), CheckUserEnum.CODE_ERROR.getMessage());
        }
        LoginByUsernameResp resp = new LoginByUsernameResp();
        resp.setUsername(user.getUsername());
        Map<String, Object> map = new HashMap<>();
        map.put("userId", user.getUserId());
        map.put("username", user.getUsername());
        resp.setToken(JWT.generateJwt(map));
        return ResponseVO.successResponse(resp);
    }

    /**
     * 用户名登录
     * @param req 用户名登录请求
     * @return 登录结果
     */
    @Override
    public ResponseVO loginByUsername(LoginByUsernameReq req) {
        //校验用户名和密码
        ResponseVO res = checkUserOrPass(req.getUsername(), req.getPassword());
        if (res != null) return res;
        //查询数据库中是否存在这个用户
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.eq("username", req.getUsername());
        queryWrapper.eq("password", req.getPassword());
        User user = userMapper.selectOne(queryWrapper);
        //不存在，返回用户不存在
        if (user == null) {
            return ResponseVO.errorResponse(CheckUserEnum.USERNAME_OR_PASS_ERROR.getCode(), CheckUserEnum.USERNAME_OR_PASS_ERROR.getMessage());
        }
        LoginByUsernameResp resp = new LoginByUsernameResp();
        BeanUtils.copyProperties(req, resp);
        Map<String, Object> map = new HashMap<>();
        map.put("userId", user.getUserId());
        map.put("username", user.getUsername());
        resp.setToken(JWT.generateJwt(map));
        //存在，登录成功
        return ResponseVO.successResponse(resp);
    }

    /**
     * 手机号绑定
     * @param req 手机号绑定请求
     * @return 绑定结果
     */
    @Override
    public ResponseVO bindingPhone(BindingPhoneReq req) {
        //校验手机号
        if (!Check.isValidPhone(req.getPhone())) {
            return ResponseVO.errorResponse(CheckUserEnum.PHONE_ERROR.getCode(), CheckUserEnum.PHONE_ERROR.getMessage());
        }
        //绑定手机号
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", req.getUserId());
        updateWrapper.set("phone", req.getPhone());
        int update = userMapper.update(null, updateWrapper);
        if (update != 1) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_NOT_EXIST.getCode(), CheckUserEnum.USER_NOT_EXIST.getMessage());
        }
        return ResponseVO.successResponse("绑定成功");
    }

    /**
     * 邮箱绑定
     * @param req 邮箱绑定请求
     * @return 绑定结果
     */
    @Override
    public ResponseVO bindingEmail(BindingEmailReq req) {
        //校验邮箱
        if (!Check.isValidEmail(req.getEmail())) {
            return ResponseVO.errorResponse(CheckUserEnum.EMAIL_ERROR.getCode(), CheckUserEnum.EMAIL_ERROR.getMessage());
        }
        //绑定邮箱
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", req.getUserId());
        updateWrapper.set("email", req.getEmail());
        int update = userMapper.update(null, updateWrapper);
        if (update != 1) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_NOT_EXIST.getCode(), CheckUserEnum.USER_NOT_EXIST.getMessage());
        }
        return ResponseVO.successResponse("绑定成功");
    }

    /**
     * 地址绑定
     * @param req 地址绑定请求
     * @return 绑定结果
     */
    @Override
    public ResponseVO bindingAddress(BindingAddressReq req) {
        //绑定邮箱
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", req.getUserId());
        updateWrapper.set("address", req.getAddress());
        int update = userMapper.update(null, updateWrapper);
        if (update != 1) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_NOT_EXIST.getCode(), CheckUserEnum.USER_NOT_EXIST.getMessage());
        }
        return ResponseVO.successResponse("绑定成功");
    }

    /**
     * 获取用户信息
     * @param userId 用户id
     * @return 用户信息
     */
    @Override
    public ResponseVO getUserInfo(Long userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        User user = userMapper.selectOne(queryWrapper);
        if(user==null){
           return ResponseVO.errorResponse(CheckUserEnum.USER_NOT_EXIST.getCode(), CheckUserEnum.USER_NOT_EXIST.getMessage());
        }
        return ResponseVO.successResponse(user);
    }

    /**
     * imei绑定
     * @param req imei绑定请求
     * @return 绑定结果
     */
    @Override
    public ResponseVO bindingImei(BindingImeiReq req) {
        //todo 查询imei号是否存在
        //绑定imei号
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", req.getUserId());
        updateWrapper.set("imei", req.getImei());
        int update = userMapper.update(null, updateWrapper);
        if (update != 1) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_NOT_EXIST.getCode(), CheckUserEnum.USER_NOT_EXIST.getMessage());
        }
        return ResponseVO.successResponse("绑定成功");
    }

    /**
     * 获取验证码
     * @param req 获取验证码请求
     * @return 验证码
     */
    @Override
    public ResponseVO getCode(GetCodeReq req) {
        String email = req.getEmail();
        if(!Check.isValidEmail(email)){
            return ResponseVO.errorResponse(CheckUserEnum.EMAIL_ERROR.getCode(), CheckUserEnum.EMAIL_ERROR.getMessage());
        }
        //发送验证码
        VerificationCodeUtils.CodeWithExpiration codeWithExpiration = VerificationCodeUtils.generateCodeWithExpiration();
      verificationCodeService.saveCode(req.getEmail(),codeWithExpiration.getCode());
        String verificationCodeHtml = VerificationCodeUtils.createVerificationCodeHtml(codeWithExpiration.getCode());
        QQEmailUtils.sendHtmlEmail(email, "验证码",verificationCodeHtml);
        return ResponseVO.successResponse("验证码发送成功");
    }

    /**
     * 校验用户名和密码
     * @param username 用户名
     * @param password 密码
     * @return 校验结果
     */
    private ResponseVO checkUserOrPass(String username, String password) {
        if (username.contains(" ")) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_OR_PASS_ERROR.getCode(), CheckUserEnum.USER_OR_PASS_ERROR.getMessage());
        }
        if (password.contains(" ")) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_OR_PASS_ERROR.getCode(), CheckUserEnum.USER_OR_PASS_ERROR.getMessage());
        }
        if (checkUsernameOrPassword(username) || checkUsernameOrPassword(password)) {
            return ResponseVO.errorResponse(CheckUserEnum.USER_OR_PASS_ERROR.getCode(), CheckUserEnum.USER_OR_PASS_ERROR.getMessage());
        }
        if (checkUsernameOrPasswordLength(username) || checkUsernameOrPasswordLength(password)) {
            return ResponseVO.errorResponse(CheckUserEnum.LEN_ERROR.getCode(), CheckUserEnum.LEN_ERROR.getMessage());
        }
        return null;
    }

    private boolean checkUsernameOrPassword(String string) {
        string = string.trim();
        return string.isEmpty();
    }

    private boolean checkUsernameOrPasswordLength(String string) {
        return string.length() < 6 || string.length() > 12;
    }

    private boolean checkUsername(String username) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        return user != null;
    }
}
